%% configuration file for Orientation channel

% input parameters
img_size_x = 256;
img_size_y = 256;
datfile = '../../saliency_ML605/saliency_c1_256.dat';
SIMULATION_SYNTHESIS = 0; % 0 : HDL simulation, 1 : Synthesis
% Algorithmic parameters

num_levels = 6;
Nc = 1;
Ns = 2;
c = [1];
delta = [3,4];
output_scale = 4;
dec_factor = 2;
pyr_window = 5;
gabor_window = 5;
resample_window = 5;
maxnorm_window = 3;
if(pyr_window == 5)      % Pyramid generator filter
    filt_coeff = [1, 4, 6, 4, 1];
    scale_coeff = 4;   % (1/16)*filt_coeff
elseif(pyr_window == 9)
    filt_coeff = [1, 4, 8, 12, 14, 12, 8, 4, 1];
    scale_coeff = 6;   % (1/64)*filt_coeff
end

if(gabor_window == 5)      % Pyramid generator filter
    gabor_filt_coeff = [1, 4, 6, 4, 1];
    gabor_scale_coeff = 4;   % (1/16)*filt_coeff
elseif(gabor_window == 9)
    gabor_filt_coeff = [1, 4, 8, 12, 14, 12, 8, 4, 1];
    gabor_scale_coeff = 6;   % (1/64)*filt_coeff
end

dec_factor_x = dec_factor;
dec_factor_y = dec_factor;

if(resample_window == 5)        % Resampling filter
    resample_filt_coeff = [1, 4, 6, 4, 1];
    resample_scale_coeff = 4;   % (1/16)*filt_coeff
elseif(resample_window == 9)
    resample_filt_coeff = [1, 4, 8, 12, 14, 12, 8, 4, 1];
    resample_scale_coeff = 6;   % (1/64)*filt_coeff
end

coeff_sig = 8;
coeff_frac = 8; % fixed pt rep of filter coeff

% Core IDs 
CORE_ID_PYRAMID = 1;
CORE_ID_CSD = 2;
CORE_ID_MAXNORM_CH = 3;
CORE_ID_RESAMPLER = 4;
CORE_ID_ASA = 5;
CORE_ID_GABOR = 6;
CORE_ID_PYR_FRAME_BUF = 7;
CORE_ID_REICHARDT = 8;
CORE_ID_MAXNORM_CONSP = 9;
CORE_ID_MAXNORM_SAL = 10;
CORE_ID_ACC_CONSP = 11;
CORE_ID_ACC_SAL = 12;

% Number of instances of each core
NUM_INST_PYR = 1;
NUM_INST_CSD = Nc;
NUM_INST_MAXNORM = Nc*Ns;
NUM_INST_RESAMPLER = Nc*Ns;
NUM_INST_ASA = 1;
NUM_INST_GABOR = num_levels-1;

q_int = quantizer('ufixed', [16,0]); %16-bit integer for img size, dec factor ..   
q24 = quantizer('ufixed', [24,20]); % 4.20 fixed pt format for norm threshold
q8 = quantizer('ufixed', [8, 0]);   %8-bit integer for core-id and instance-id
q_fixed = quantizer('ufixed', [16,8]);  %8.8 format for filter coeffs

%% Pyramid generator

core_id = num2hex(q8, CORE_ID_PYRAMID);  %core_id
inst_id = num2hex(q8, 0);    %instance_id
pad = num2hex(q_int, 0);    %zero pad

config_data = [pad, core_id, inst_id, num2hex(q_int, img_size_x), num2hex(q_int, img_size_y)];                   %image size
config_data = [config_data; [pad, core_id, inst_id, num2hex(q_int, dec_factor_x), num2hex(q_int, dec_factor_y)]];  % decimate factor
for i = 1:pyr_window                           % filter coeffs - most significant coeff goes in first
    config_data = [config_data; [pad, core_id, inst_id, num2hex(q_int, 0), num2hex(q_fixed, filt_coeff(pyr_window-i+1))]];   
end

config_data = [config_data; [pad, core_id, inst_id, num2hex(q_int, 0), num2hex(q_int, scale_coeff)]];    %scale coefficient
config_data = [config_data; [pad, core_id, inst_id, num2hex(q_int, coeff_sig), num2hex(q_int, coeff_frac)]]; %8.8 rep of filter coeffs

%% Gabor filter wrapper
core_id = num2hex(q8, CORE_ID_GABOR);  %core_id

for i = 1:NUM_INST_GABOR   
    inst_id = num2hex(q8, (i-1));    %instance_id
    
    pyr_level = i;    %pyramid level for gabor % level 0 is not used for gabor
    pyr_img_size_y = img_size_y/(dec_factor^pyr_level); %pyramid level img size
    pyr_img_size_x = img_size_x/(dec_factor^pyr_level);    
    
    config_data = [config_data; [pad, core_id, inst_id, num2hex(q_int, pyr_img_size_x), num2hex(q_int, pyr_img_size_y)]];  %image size
    %config_data = [config_data; [pad, core_id, inst_id, num2hex(q_int, dec_factor_x), num2hex(q_int, dec_factor_y)]];  % decimate factor
    for i = 1:gabor_window                           % filter coeffs - most significant coeff goes in first
        config_data = [config_data; [pad, core_id, inst_id, num2hex(q_int, 0), num2hex(q_fixed, gabor_filt_coeff(gabor_window-i+1))]];   
    end

    config_data = [config_data; [pad, core_id, inst_id, num2hex(q_int, 0), num2hex(q_int, gabor_scale_coeff)]];    %scale coefficient
    config_data = [config_data; [pad, core_id, inst_id, num2hex(q_int, coeff_sig), num2hex(q_int, coeff_frac)]]; %8.8 rep of filter coeffs   
    
end

%% CSD

nr = img_size_y;
nc = img_size_x;

core_id = num2hex(q8, CORE_ID_CSD);  %core_id
surround = zeros(1,Ns);
surround_nr = zeros(1,Ns);
surround_nc = zeros(1,Ns);

for i = 1:NUM_INST_CSD    
    inst_id = num2hex(q8, (i-1));    %instance_id
    center = c(i); %center channel for csd
    center_nr = nr/(dec_factor^center); %center channel img size
    center_nc = nc/(dec_factor^center);
    
    config_data = [config_data; [pad, core_id, inst_id, num2hex(q_int, center_nc), num2hex(q_int, center_nr)]];  %center image size
    
    for j = 1:Ns% surround channels - most significant coeff goes in first   
        surround(j) = center + delta(Ns-j+1);   % surround channel for csd = c + delta
        surround_nr(j) = nr/(dec_factor^surround(j)); % surround channel img size
        surround_nc(j) = nc/(dec_factor^surround(j));
        cs_factor(j) = dec_factor^(surround(j) - center);    % decimate factor b/w center-surround        
        config_data = [config_data; [pad, core_id, inst_id, num2hex(q_int, surround_nc(j)), num2hex(q_int, surround_nr(j))]]; % surround image size       
    end
    
    for j = 1:Ns% surround channels - most significant coeff goes in first
        config_data = [config_data; [pad, core_id, inst_id, num2hex(q_int, cs_factor(j)), num2hex(q_int, cs_factor(j))]];    % cs_factor
    end
end

%% Max normalizer per Channel
core_id = num2hex(q8, CORE_ID_MAXNORM_CH);  %core_id


Threshold = 0;

for i = 1:Nc   
    center = c(i);    %center channel for csd
    center_nr = nr/(dec_factor^center); %center channel img size
    center_nc = nc/(dec_factor^center);
    for j = 1:Ns     % surround channel
        inst_id = num2hex(q8, ((i-1)*Ns+j-1));    %instance_id
        config_data = [config_data; [pad, core_id, inst_id, num2hex(q_int, center_nc), num2hex(q_int, center_nr)]];  %image size
        config_data = [config_data; [pad, core_id, inst_id, num2hex(q8, 0), num2hex(q24, Threshold)]];               % threshold
    end
end
%% Resampler
core_id = num2hex(q8, CORE_ID_RESAMPLER);  %core_id

for i = 1:Nc   
    center = c(i);    %center channel for csd
    center_nr = nr/(dec_factor^center); %center channel img size
    center_nc = nc/(dec_factor^center);
    for j = 1:Ns     % surround channel
        inst_id = num2hex(q8, ((i-1)*Ns+j-1));    %instance_id
        config_data = [config_data; [pad, core_id, inst_id, num2hex(q_int, center_nc), num2hex(q_int, center_nr)]];  %img_size
        
        config_data = [config_data; [pad, core_id, inst_id, num2hex(q_int, dec_factor_x), num2hex(q_int, dec_factor_y)]];    %dec_factor
        for k = 1:resample_window                   % filter coeffs - most significant coeff goes in first
            config_data = [config_data; [pad, core_id, inst_id, num2hex(q_int, 0), num2hex(q_fixed, resample_filt_coeff(resample_window-k+1))]];
        end

        config_data = [config_data; [pad, core_id, inst_id, num2hex(q_int, 0), num2hex(q_int, resample_scale_coeff)]];   %scale coeff
        config_data = [config_data; [pad, core_id, inst_id, num2hex(q_int, coeff_sig), num2hex(q_int, coeff_frac)]]; %8.8 rep of filter coeffs
        
    end
end
%% Across-scale adder

core_id = num2hex(q8, CORE_ID_ASA);  %core_id
inst_id = num2hex(q8, 0);    %instance_id

output_nr = nr/(dec_factor^output_scale); %output channel img size
output_nc = nc/(dec_factor^output_scale);
config_data = [config_data; [pad, core_id, inst_id, num2hex(q_int, output_nc), num2hex(q_int, output_nr)]];       %image size

%% Max normalizer for Conspicuity (outnorm)
core_id = num2hex(q8, CORE_ID_MAXNORM_CONSP);  %core_id
inst_id = num2hex(q8, 0);    %instance_id
Threshold = 0;

config_data = [config_data; [pad, core_id, inst_id, num2hex(q_int, output_nc), num2hex(q_int, output_nr)]];  %image size
config_data = [config_data; [pad, core_id, inst_id, num2hex(q8, 0), num2hex(q24, Threshold)]];               % threshold
%% Max normalizer for Saliency (Salnorm)
core_id = num2hex(q8, CORE_ID_MAXNORM_SAL);  %core_id
inst_id = num2hex(q8, 0);    %instance_id
Threshold = 0;

config_data = [config_data; [pad, core_id, inst_id, num2hex(q_int, output_nc), num2hex(q_int, output_nr)]];  %image size
config_data = [config_data; [pad, core_id, inst_id, num2hex(q8, 0), num2hex(q24, Threshold)]];               % threshold
%% Finish
core_id = num2hex(q8, 16);  %core_id
inst_id = num2hex(q8, 0);    %instance_id
config_data = [config_data; [pad, core_id, inst_id, num2hex(q_int, 0), num2hex(q_int, 0)]];            %Flush packet

%% Write to a file

fid = fopen(datfile, 'w');

if (SIMULATION_SYNTHESIS==1)    % for on-board test with PLB - each line is 32-bit wide
    for i=1:size(config_data,1)
        fprintf(fid,'%8s\n', config_data(i,1:8));
        fprintf(fid,'%8s\n', config_data(i,9:16));
    end    
else
    for i=1:size(config_data,1)     % for simulation - each line is 64-bit wide
        fprintf(fid,'%16s\n', config_data(i,:));
    end
end
fclose(fid);
